Skip to content

feat!: no_from#21716

Merged
Thunkar merged 28 commits intomerge-train/fairiesfrom
gj/no_from
Mar 18, 2026
Merged

feat!: no_from#21716
Thunkar merged 28 commits intomerge-train/fairiesfrom
gj/no_from

Conversation

@Thunkar
Copy link
Contributor

@Thunkar Thunkar commented Mar 18, 2026

Getting rid of the tyranny of the Account entrypoint, and the terrible sentinel value of AztecAddress.ZERO in the from parameter.

Now, when a tx is specified as being sent from: NO_FROM, the wallet completely bypasses the account contract. It doesn't even use the MulticallEntrypoint contract, it'll just execute a single call using DefaultEntrypoint. Since we can do wrapping at the app level, this means ANYTHING goes. Want to wrap 10 calls on a special sauce multicall? Go ahead. App-sponsored FPC with custom logic that must be the first on the chain? Knock yourself out!

Even better news: this is thoroughly tested in our codebase thanks to account contract self-deployments. They're a great example of "I don't want to use an account contract as entrypoint" flow.

As an extra side effect, this completely deshrines the MulticallEntrypoint protocol contract from the wallet (we only have the convenience now of it being already registered in every single wallet)

@Thunkar Thunkar added the ci-draft Run CI on draft PRs. label Mar 18, 2026
@Thunkar Thunkar added the ci-no-fail-fast Sets NO_FAIL_FAST in the CI so the run is not aborted on the first failure label Mar 18, 2026
@Thunkar Thunkar marked this pull request as ready for review March 18, 2026 09:00
@Thunkar Thunkar requested review from a team and nventuro as code owners March 18, 2026 09:00
@Thunkar Thunkar requested review from mverzilli and nchamo March 18, 2026 09:48

const deployOpts: DeployAccountOptions<InteractionWaitOptions> = {
from: AztecAddress.ZERO,
from: NO_FROM,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NO_FROM sounds so strange, isn't there some other way to name this hinting at its effects? maybe something like PAYLOAD_DEFINED_FROM (which is probably wronger and horribler, but I'm trying to convey my objection)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

seeing the changes to the docs, maybe CREATED_BY_TX

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not in love with the naming too, I went for parallelism with NO_WAIT...

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is weird, yes, but I'm also having trouble coming up with something better. Perhaps from: DIRECT_CALL? idk

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree that NO_FROM sounds strange. Now that Claude is back up, it suggested a few options:

  • DIRECT or DIRECT_EXECUTION -- signals that the tx bypasses the account contract entrypoint
  • NO_ACCOUNT -- clearer that you're opting out of account contract wrapping
  • RAW -- short, implies no wrapping/mediation
  • SELF -- the transaction acts on its own behalf without an intermediary account contract
  • UNMEDIATED -- explicitly says "no account contract mediation"
  • ENTRYPOINTLESS -- describes the mechanism being skipped (the account entrypoint)
  • NO_SENDER -- closer to the domain: there's no "sender" account wrapping the call

And it even provided a ranking 😅

My ranking would be: DIRECT > NO_ACCOUNT > NO_SENDER > SELF > UNMEDIATED > ENTRYPOINTLESS > RAW > NO_FROM.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry but all of those are worse IMO xD

from is pretty generic, it has no concept of account (wallet just happens to make it so from is an account, but we had the exception of the multicall entrypoint...which is not one). The NO_WAIT parallel is also a pro in my book

Comment on lines +229 to +257
let overrides: SimulationOverrides | undefined;
let txRequest: TxExecutionRequest;
if (from === NO_FROM) {
const entrypoint = new DefaultEntrypoint();
txRequest = await entrypoint.createTxExecutionRequest(finalExecutionPayload, feeOptions.gasSettings, chainInfo);
} else {
const useOverride = this.simulationMode === 'kernelless-override';
let fromAccount: Account;
if (useOverride) {
const { account, instance, artifact } = await this.getFakeAccountDataFor(from);
fromAccount = account;
overrides = {
contracts: { [from.toString()]: { instance, artifact } },
};
} else {
fromAccount = await this.getAccountFromAddress(from);
}
const executionOptions: DefaultAccountEntrypointOptions = {
txNonce: Fr.random(),
cancellable: this.cancellableTransactions,
feePaymentMethodOptions: feeOptions.accountFeePaymentMethodOptions,
};
txRequest = await fromAccount.createTxExecutionRequest(
finalExecutionPayload,
feeOptions.gasSettings,
chainInfo,
executionOptions,
);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: extract this to an aux function that gives you { txRequest, overrides } so we can use early returns and avoid the fat else branch

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this is in itself a helper, I didn't want to muddy the waters further...I think it conveys "bare entrypoint vs. account contract well". But maybe I'm just too brain damaged by now

Copy link
Contributor

@mverzilli mverzilli left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This makes a ton of sense and the implementation looks solid, my only concern is with NO_FROM naming given it's gonna be public API. I don't have a strong enough alternative I can propose so approving, maybe I would run this through people with a less close perspective of the codebase (eg devrel, Wonder, Ciara, etc)


const deployOpts: DeployAccountOptions<InteractionWaitOptions> = {
from: AztecAddress.ZERO,
from: NO_FROM,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is weird, yes, but I'm also having trouble coming up with something better. Perhaps from: DIRECT_CALL? idk

Comment on lines +17 to +19
console.error(
"data.json not found. Run 'yarn data' first to generate proof data.",
);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is your formatter configured to fewer than 120 chars?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the doc examples are...weird. I cannot get the ts server to behave with them and editing them does whatever. They also take forever to build...we have to talk to devrel about this

Comment on lines +163 to +164
// Account contracts are always universally deployed (deployer = ZERO),
// but we still need to know the original `from` to detect self-deployment.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are they always universally deplyoed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Convention. Nothing prevents us from doing it differently

Copy link
Contributor

@nchamo nchamo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work!

@Thunkar Thunkar merged commit 2257864 into merge-train/fairies Mar 18, 2026
11 checks passed
@Thunkar Thunkar deleted the gj/no_from branch March 18, 2026 20:53
@AztecBot
Copy link
Collaborator

❌ Failed to cherry-pick to v4-next due to conflicts. (🤖) View backport run.

AztecBot added a commit that referenced this pull request Mar 19, 2026
… call

The no_from PR (#21716) changed how AztecAddress.ZERO is handled in the
embedded wallet simulate path. The simulate call in setupAccountWithPrivateKey
was using AztecAddress.ZERO as the from address, which now causes the wallet
to attempt looking up account data for the zero address (which doesn't exist).
Changed to use NO_FROM which is the correct API for opting out of account
contract mediation during simulation.
Maddiaa0 pushed a commit that referenced this pull request Mar 19, 2026
…#21402)

## Summary
The `feat!: no_from` PR (#21716) changed how `AztecAddress.ZERO` is
handled in the embedded wallet's simulate path.
`BotFactory.setupAccountWithPrivateKey` was passing `AztecAddress.ZERO`
as the `from` address in the `simulate` call, which now causes the
wallet to attempt looking up account data for the zero address —
resulting in `"Account 0x000...000 does not exist on this wallet"`.

Fixed by using `NO_FROM` (already imported and used in the adjacent
`send` call) which is the correct API for opting out of account contract
mediation during simulation.

## Failing tests fixed
- `e2e_bot › bridge resume › reuses prior bridge claims`
- `e2e_bot › bridge resume › does not reuse prior bridge claims if
recipient address changes`
- `e2e_bot › setup via bridging funds cross-chain › creates bot after
inbox drift`

## Test plan
- All 10 e2e_bot tests pass locally (previously 3 were failing)

ClaudeBox log: https://claudebox.work/s/11a8e25f0aefa248?run=1
Thunkar added a commit that referenced this pull request Mar 19, 2026
## Summary
Backports #21716 to
v4-next via `backport-to-v4-next-staging`.

Based on latest `backport-to-v4-next-staging` which has #21646 (gas
estimations on send), so this PR contains only #21716's actual changes
(NO_FROM pattern).

Cherry-pick conflicts resolved:
- `bot/src/factory.ts` — `AztecAddress.ZERO` → `NO_FROM`
- `e2e_fees/account_init.test.ts` — `AztecAddress.ZERO` → `NO_FROM`
- `docs/examples/ts/recursive_verification/index.ts` — imports + data
loading updated
- `docs/examples/ts/aztecjs_connection/index.ts` — `AztecAddress.ZERO` →
`NO_FROM` in existing fee juice section, discarded duplicate sections
from cherry-pick
- `spartan/block_capacity.test.ts` — deleted (already removed on
v4-next)

## Key changes
- Introduces `NO_FROM` pattern replacing `AztecAddress.ZERO` sentinel
for bypassing account contract entrypoint
- Removes `SignerlessAccountContract`
- Uses `DefaultEntrypoint` directly when `from: NO_FROM`
- Deshrines `MulticallEntrypoint` from wallet internals

---------

Co-authored-by: Gregorio Juliana <gregojquiros@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backport-to-v4-next ci-draft Run CI on draft PRs. ci-no-fail-fast Sets NO_FAIL_FAST in the CI so the run is not aborted on the first failure

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants